#-------------------------------------------------------------------------------
# Copyright (c) 2012 Huseyin BIYIK.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the GNU Public License v3.0
# which accompanies this distribution, and is available at
# http://www.gnu.org/licenses/gpl.html
# 
# Contributors:
#     Huseyin BIYIK - initial API and implementation
#-------------------------------------------------------------------------------
import threading
from defs import *
from stack import *
from call import call as callobj
import devices.audio
import time

class crowd():
	def __init__(self, laddr, lport, loopback=False):
		self.laddr = laddr
		self.lport = lport
		self.ai = devices.audio.audio_interface()
		self.interfaces = {}
		self.interfaces["audio"] = {"in":self.ai.in_func, "out":self.ai.out_func}
		self.interfaces["video"] = {"in":null_func, "out":null_func}
		self.interfaces["text"] = {"in":null_func, "out":null_func}
		self.interfaces["other"] = {"in":null_func, "out":null_func}
		self.stack = stack(self, laddr, lport,loopback=loopback)
		self.cm = self.stack.cm

	def close(self):
		logger.info("Closing crowd api")
		self.stack.close()


	def _on_datareceived(self, args):
		pass
	
	def _on_call_established(self, args):
		pass
		
	def _on_call_declined(self, args):
		pass
	
	def _on_call_requested(self, cll):
		##consider some sanity checks in case for memory leak ie: create a new call or stream...
		return self.on_call_requested(cll)

	def on_call_requested(self, cll):
		for typ in cll.stream.get_types():
			cll.stream.set_type(typ.name,"out_func",self.interfaces[typ.name]["out"])
			cll.stream.set_type(typ.name,"enabled",True)
			logger.info("Call '%s' with '%s' stream has automatically been accepted", cll.id, typ.name)
		return cll

	def write_data(self, call, dtype, payload):
		if dtype == "audio":
			self.send_data([call], dtype, payload)

	def send_data(self, calls, dtype, payload):
		for call in calls:
			if not call is None:
				self.stack.sender.add(4, call, {'dtype':dtype, 'payload':payload})

	def make_call(self, raddr, rport, dtype, value=True):
		cll = callobj(0, self.laddr, self.lport, raddr, rport)
		cll.stream.set_type(dtype, "enabled", True)
		cll.stream.set_type(dtype, "timestamp", time.time())
		cll.stream.set_type(dtype, "payload", "")
		cll.stream.set_type(dtype, "out_func", self.interfaces[dtype]["out"])
		self.stack.sender(0, cll)
